package com.knowledgegraph.neo4j.service.impl;

import com.knowledgegraph.neo4j.entity.GraphEntity;
import com.knowledgegraph.neo4j.repository.GraphEntityRepository;
import com.knowledgegraph.neo4j.service.Neo4jEntityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Neo4j 实体服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class Neo4jEntityServiceImpl implements Neo4jEntityService {
    
    private final GraphEntityRepository graphEntityRepository;
    
    @Override
    @Transactional
    public GraphEntity createEntity(GraphEntity entity) {
        entity.setCreateTime(LocalDateTime.now());
        entity.setUpdateTime(LocalDateTime.now());
        entity.setStatus("active");
        
        if (entity.getConfidence() == null) {
            entity.setConfidence(1.0);
        }
        
        log.info("创建实体: {}", entity.getName());
        return graphEntityRepository.save(entity);
    }
    
    @Override
    @Transactional
    public GraphEntity updateEntity(GraphEntity entity) {
        Optional<GraphEntity> existingEntity = graphEntityRepository.findById(entity.getId());
        if (existingEntity.isPresent()) {
            GraphEntity existing = existingEntity.get();
            existing.setName(entity.getName());
            existing.setType(entity.getType());
            existing.setDescription(entity.getDescription());
            existing.setProperties(entity.getProperties());
            existing.setConfidence(entity.getConfidence());
            existing.setUpdateTime(LocalDateTime.now());
            
            log.info("更新实体: {}", entity.getName());
            return graphEntityRepository.save(existing);
        }
        throw new RuntimeException("实体不存在: " + entity.getId());
    }
    
    @Override
    @Transactional
    public void deleteEntity(Long entityId) {
        log.info("删除实体: {}", entityId);
        graphEntityRepository.deleteById(entityId);
    }
    
    @Override
    public GraphEntity findById(Long entityId) {
        return graphEntityRepository.findById(entityId)
                .orElseThrow(() -> new RuntimeException("实体不存在: " + entityId));
    }
    
    @Override
    public List<GraphEntity> findByGraphId(Long graphId) {
        return graphEntityRepository.findByGraphId(graphId);
    }
    
    @Override
    public List<GraphEntity> findByType(String type) {
        return graphEntityRepository.findByType(type);
    }
    
    @Override
    public List<GraphEntity> searchEntities(Long graphId, String keyword) {
        return graphEntityRepository.searchEntities(graphId, keyword);
    }
    
    @Override
    public Map<String, Object> getEntityStatistics(Long graphId) {
        List<GraphEntity> entities = graphEntityRepository.findByGraphId(graphId);
        
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalCount", entities.size());
        statistics.put("typeCount", entities.stream().map(GraphEntity::getType).distinct().count());
        statistics.put("highConfidenceCount", entities.stream()
                .filter(e -> e.getConfidence() != null && e.getConfidence() > 0.8)
                .count());
        
        return statistics;
    }
    
    @Override
    public List<Map<String, Object>> getEntityTypeDistribution(Long graphId) {
        return graphEntityRepository.countEntitiesByType(graphId);
    }
    
    @Override
    public Map<String, Object> getEntityWithRelations(Long entityId) {
        List<Map<String, Object>> result = graphEntityRepository.findEntityWithRelations(entityId);
        
        Map<String, Object> entityData = new HashMap<>();
        if (!result.isEmpty()) {
            entityData.put("entity", result.get(0).get("e"));
            entityData.put("relations", result);
        }
        
        return entityData;
    }
    
    @Override
    public List<Map<String, Object>> getEntityNeighbors(Long entityId) {
        return graphEntityRepository.findNeighbors(entityId);
    }
    
    @Override
    public List<Map<String, Object>> getImportantEntities(Long graphId, Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        return graphEntityRepository.findImportantEntities(graphId, limit);
    }
    
    @Override
    @Transactional
    public List<GraphEntity> batchCreateEntities(List<GraphEntity> entities) {
        LocalDateTime now = LocalDateTime.now();
        
        entities.forEach(entity -> {
            entity.setCreateTime(now);
            entity.setUpdateTime(now);
            entity.setStatus("active");
            if (entity.getConfidence() == null) {
                entity.setConfidence(1.0);
            }
        });
        
        log.info("批量创建实体: {} 个", entities.size());
        return (List<GraphEntity>) graphEntityRepository.saveAll(entities);
    }
    
    @Override
    public List<GraphEntity> findByGraphIdAndType(Long graphId, String type) {
        return graphEntityRepository.findByGraphIdAndType(graphId, type);
    }
}